home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i002: Georgia Tech 'se' Screen Editor
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: emoryu1!arnold (Arnold D. Robbins)
- Mod.sources: Volume 8, Issue 2
- Archive-name: se/Part02
-
-
- Here is the second release of the Georgia Tech Screen Editor, 'se'.
- There were enough changes that a whole new posting is warranted.
-
- Major Changes:
- All Georgia Tech specific stuff removed.
- It understands window size changes on 4.3BSD and ATT Unix PC/3B1
- Support for the shared library on the ATT Unix PC/3B1
- Considerable source code reorganization in certain files.
-
- Enjoy,
-
- Arnold Robbins
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # edit.c
- # extern.h
- # m4munge
- # main.c
- # makefile
- # misc.c
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'edit.c'" '(26346 characters)'
- if test -f 'edit.c'
- then
- echo shar: will not over-write existing file "'edit.c'"
- else
- cat << \SHAR_EOF > 'edit.c'
- #ifndef lint
- static char RCSid[] = "$Header: edit.c,v 1.3 86/07/11 15:11:34 osadr Exp $";
- #endif
-
- /*
- * $Log: edit.c,v $
- * Revision 1.3 86/07/11 15:11:34 osadr
- * Removed Georgia Tech specific code.
- *
- * Revision 1.2 86/05/27 17:44:56 osadr
- * Removed flexnames dependancy; PREVLINE[2] --> PREVLN[2].
- * Improved the sysname() routine, particularly to use the nodename
- * member of the utsname structure under System V.
- *
- * Revision 1.1 86/05/06 13:37:16 osadr
- * Initial revision
- *
- *
- */
-
- /*
- ** edit.c
- **
- ** editor main routine, plus other routines used a lot.
- */
-
- #include "se.h"
- #include "extern.h"
-
- static char Savknm = DEFAULTNAME; /* saved mark name for < and > */
-
- /* edit --- main routine for screen editor */
-
- edit (argc, argv)
- int argc;
- char *argv[];
- {
- int cursav, status, len, cursor;
- int ckglob (), docmd (), doglob (), doread ();
- int getlst (), nextln (), prevln ();
- char lin[MAXLINE], term;
-
- watch (); /* display time of day */
-
- #ifdef LOG_USAGE
- log (); /* log who used the program */
- #endif
-
- serc (); /* execute commands in ./.serc or $HOME/.serc */
-
- status = OK;
-
- while (status == OK && Argno < argc)
- {
- strcpy (lin, argv[Argno]);
- loadstr (lin, Argno, POOPCOL, Ncols);
- if (lin[0] == '-')
- {
- len = strlen (lin) + 1;
- lin[len - 1] = '\n';
- lin[len] = EOS;
- len = 0;
- status = doopt (lin, &len);
- }
- else
- {
- dfltsopt (lin);
- status = doread (Lastln, lin, NO);
- }
- Argno++;
- }
-
- if (status == ERR)
- {
- if (Errcode == EHANGUP)
- hangup ();
- printverboseerrormessage ();
- }
- else
- Curln = min (1, Lastln);
-
- Buffer_changed = NO;
- First_affected = 1; /* maintained by updscreen & commands */
- updscreen ();
-
- if (status != ERR) /* leave offending file name or option */
- lin[0] = EOS;
- cursor = 0;
-
- /* main command loop */
- do {
- intrpt (); /* discard pending breaks (interrupts) */
- if (Lost_lines > GARB_THRESHOLD
- && (Lastln + Limcnt) / Lost_lines <= GARB_FACTOR)
- garbage_collect ();
-
- mswait (); /* check for pending messages */
- Cmdrow = Botrow + 1; /* reset the command line location */
- prompt ("cmd>");
- getcmd (lin, 0, &cursor, &term);
- remark (""); /* clear out any error messages */
-
- while (term == CURSOR_UP || term == CURSOR_DOWN
- || term == CURSOR_SAME)
- {
- switch (term) {
- case CURSOR_UP:
- if (Curln > 1)
- Curln--;
- else
- Curln = Lastln;
- break;
-
- case CURSOR_DOWN:
- if (Curln < Lastln)
- Curln++;
- else
- Curln = min (1, Lastln);
- break;
- }
- adjust_window (Curln, Curln);
- updscreen ();
- getcmd (lin, 0, &cursor, &term);
- }
-
- prompt (""); /* remove prompt */
-
- cursav = Curln; /* remember it in case of an error */
- Errcode = EEGARB; /* default error code for garbage at end */
-
- len = 0;
- if (getlst (lin, &len, &status) == OK)
- {
- if (ckglob (lin, &len, &status) == OK)
- doglob (lin, &len, &cursav, &status);
- else if (status != ERR)
- docmd (lin, len, NO, &status);
- }
- if (status == ERR)
- {
- if (Errcode == EHANGUP)
- hangup ();
- printverboseerrormessage ();
- Curln = min (cursav, Lastln);
- }
- else if (term != FUNNY)
- {
- cursor = 0;
- lin[0] = EOS;
- }
-
- adjust_window (Curln, Curln);
- updscreen ();
-
- } while (status != EOF);
-
- clrscreen ();
- clrbuf ();
- tflush ();
-
- return;
- }
-
-
- /* getlst --- collect line numbers (if any) at lin[*i], increment i */
-
- int getlst (lin, i, status)
- char lin[];
- int *i, *status;
- {
- int num;
- int getone ();
-
- Line2 = 0;
- for (Nlines = 0; getone (lin, i, &num, status) == OK; )
- {
- Line1 = Line2;
- Line2 = num;
- Nlines++;
- if (lin[*i] != ',' && lin[*i] != ';')
- break;
- if (lin[*i] == ';')
- Curln = num;
- (*i)++;
- }
-
- if (Nlines > 2)
- Nlines = 2;
-
- if (Nlines <= 1)
- Line1 = Line2;
-
- if (Line1 > Line2)
- {
- *status = ERR;
- Errcode = EBACKWARD;
- }
-
- if (*status != ERR)
- *status = OK;
-
- return (*status);
- }
-
-
- /* getnum --- convert one term to line number */
-
- int getnum (lin, i, pnum, status)
- char lin[];
- register int *i, *pnum, *status;
- {
- int j, ret;
- int ctoi (), optpat (), ptscan (), knscan (), getkn ();
- int k;
-
- ret = OK;
- SKIPBL (lin, *i);
- if (lin[*i] >= Rel_a && lin[*i] <= Rel_z && Absnos == NO)
- *pnum = Topln - Toprow + lin[*i] - Rel_a;
- else if (lin[*i] == CURLINE)
- *pnum = Curln;
- else if (lin[*i] == PREVLN || lin[*i] == PREVLN2)
- *pnum = Curln - 1;
- else if (lin[*i] == LASTLINE)
- *pnum = Lastln;
- else if (lin[*i] == SCAN || lin[*i] == BACKSCAN)
- {
- int missing_delim = YES;
-
- /* see if trailing delim supplied, since command can follow pattern */
- for (k = *i + 1; lin[k] != EOS; k++)
- if (lin[k] == ESCAPE)
- k++; /* skip esc, loop will skip escaped char */
- else if (lin[k] == lin[*i])
- {
- missing_delim = NO;
- break;
- }
- /* else
- continue */
-
- if (missing_delim == YES)
- {
- for (; lin[k] != EOS; k++)
- ;
- k--; /* k now at newline */
-
- /* supply trailing delim */
- lin[k] = lin[*i];
- lin[++k] = '\n';
- lin[++k] = EOS;
- Peekc = SKIP_RIGHT;
- }
-
- if (optpat (lin, i) == ERR)
- ret = ERR;
- else if (lin[*i] == SCAN)
- ret = ptscan (FORWARD, pnum);
- else
- ret = ptscan (BACKWARD, pnum);
- }
- else if (lin[*i] == SEARCH || lin[*i] == BACKSEARCH)
- {
- j = *i;
- (*i)++;
- if (getkn (lin, i, &Savknm, Savknm) == ERR)
- ret = ERR;
- else if (lin[j] == SEARCH)
- ret = knscan (FORWARD, pnum);
- else
- ret = knscan (BACKWARD, pnum);
- (*i)--;
- }
- else if (isdigit (lin[*i]))
- {
- *pnum = ctoi (lin, i);
- (*i)--;
- }
- else if (lin[*i] == TOPLINE)
- *pnum = Topln;
- else
- ret = EOF;
-
- if (ret == OK)
- (*i)++;
- *status = ret;
- return (ret);
- }
-
-
- /* getone --- evaluate one line number expression */
-
- int getone (lin, i, num, status)
- char lin[];
- register int *i, *num, *status;
- {
- int pnum, ret;
- int getnum ();
- char porm; /* "plus or minus" (sic) */
-
- ret = EOF; /* assume we won't find anything for now */
- *num = 0;
-
- if (getnum (lin, i, num, status) == OK) /* first term */
- {
- ret = OK; /* to indicate we've seen something */
- do { /* + or - terms */
- porm = EOS;
- SKIPBL (lin, *i);
- if (lin[*i] == '-' || lin[*i] == '+')
- {
- porm = lin[*i];
- (*i)++;
- }
- if (getnum (lin, i, &pnum, status) == OK)
- if (porm == '-')
- *num -= pnum;
- else
- *num += pnum;
- if (*status == EOF && porm != EOS) /* trailing + or - */
- *status = ERR;
- } while (*status == OK);
- }
-
- if (*num < 0 || *num > Lastln) /* make sure number is in range */
- {
- *status = ERR;
- Errcode = EORANGE;
- }
-
- if (*status == ERR)
- ret = ERR;
- else
- *status = ret;
-
- return (ret);
- }
-
-
- #ifndef OLD_SCRATCH
- #ifndef OLD_GLOB
- static int special_casing = NO;
- #endif
- #endif
-
- /* ckglob --- if global prefix, mark lines to be affected */
-
- int ckglob (lin, i, status)
- char lin[];
- int *i, *status;
- {
- register int line, tmp;
- int usepat, usemark;
- int defalt (), match (), optpat (), getkn ();
- register LINEDESC *k;
- LINEDESC *gettxt (), *getind ();
-
- *status = OK;
- usepat = EOF;
- usemark = EOF;
-
- #ifndef OLD_SCRATCH
- #ifndef OLD_GLOB
- if ( /* g/^/m0 or g/$/m0 -- special case the pathological */
- /* cases in order to save time */
- (lin[*i] == GLOBAL || lin[*i] == UCGLOBAL)
- && (lin[*i + 1] == lin[*i + 3])
- && (lin[*i + 2] == '^' || lin[*i + 2] == '$')
- && (lin[*i + 4] == MOVECOM || lin[*i + 4] == UCMOVECOM)
- && (lin[*i + 5] == '0' && lin[*i + 6] == '\n') )
- {
- special_casing = YES;
- remark ("GLOB");
- return (OK);
- }
- #endif
- #endif
- if (lin[*i] == GMARK || lin[*i] == XMARK) /* global markname prefix? */
- {
- if (lin[*i] == GMARK) /* tag lines with the specified markname */
- usemark = YES;
- else /* tag lines without the specified markname */
- usemark = NO;
- (*i)++;
- *status = getkn (lin, i, &Savknm, Savknm);
- }
-
- if (*status == OK) /* check for a pattern prefix too */
- {
- if (lin[*i] == GLOBAL || lin[*i] == UCGLOBAL)
- usepat = YES;
-
- if (lin[*i] == EXCLUDE || lin[*i] == UCEXCLUDE)
- usepat = NO;
-
- if (usepat != EOF)
- {
- (*i)++;
- if (optpat (lin, i) == ERR)
- *status = ERR;
- else
- (*i)++;
- }
- }
-
- if (*status == OK && usepat == EOF && usemark == EOF)
- *status = EOF;
- else if (*status == OK)
- defalt (1, Lastln);
-
- if (*status == OK) /* no errors so far, safe to proceed */
- {
- remark ("GLOB");
-
- k = Line0; /* unmark all lines preceeding range */
- for (line = 0; line < Line1; line++)
- {
- k -> Globmark = NO;
- k = NEXTLINE(k);
- }
-
- for (; line <= Line2; line++) /* mark lines in range */
- {
- if (intrpt ())
- {
- *status = ERR;
- return (*status);
- }
- tmp = NO;
- if (usemark == EOF
- || usemark == YES && k -> Markname == Savknm
- || usemark == NO && k -> Markname != Savknm)
- {
- if (usepat == EOF) /* no global pattern to look for */
- tmp = YES;
- else /* there is also a pattern to look for */
- {
- gtxt (k);
- if (match (Txt, Pat) == usepat)
- tmp = YES;
- }
- }
-
- k -> Globmark = tmp;
-
- k = NEXTLINE(k);
- }
-
- #ifdef OLD_SCRATCH
- /* mark remaining lines */
- for (; k != Line0; k = k -> Nextline)
- k -> Globmark = NO;
- #else
- /* mark remaining lines */
- for (; line <= Lastln; line++)
- {
- k -> Globmark = NO;
- k = NEXTLINE (k);
- }
- #endif
-
- remark ("");
- }
-
- return (*status);
- }
-
-
- /* doglob --- do command at lin[i] on all marked lines */
-
- int doglob (lin, i, cursav, status)
- char lin[];
- int *i, *cursav, *status;
- {
- register int istart, line;
- int docmd (), getlst (), nextln ();
- register LINEDESC *k;
- LINEDESC *getind ();
-
- #ifndef OLD_SCRATCH
- #ifndef OLD_GLOB
- if (special_casing)
- {
- /*
- remark ("Warp 7, Captain!");
- */
- /* not on the screen too long anyway */
- reverse (1, Lastln);
- Curln = Lastln;
- special_casing = NO;
- Buffer_changed = YES;
- First_affected = min (1, First_affected);
- remark ("");
- adjust_window (Curln, Curln);
- updscreen ();
- return (OK);
- }
- #endif
- #endif
- *status = OK;
- istart = *i;
- k = Line0;
- line = 0;
-
- do {
- line++;
- k = NEXTLINE(k);
- if (k -> Globmark == YES) /* line is marked */
- {
- k -> Globmark = NO; /* unmark the line */
- Curln = line;
- *cursav = Curln; /* remember where we are */
- *i = istart;
- if (getlst (lin, i, status) == OK)
- docmd (lin, *i, YES, status);
- line = 0; /* lines may have been moved */
- k = Line0;
- }
- if (intrpt ())
- *status = ERR;
- } while (line <= Lastln && *status == OK);
-
- return (*status);
- }
-
-
- /* ckchar --- look for ch or altch on lin at i, set flag if found */
-
- int ckchar (ch, altch, lin, i, flag, status)
- char ch, altch, lin[];
- int *i, *flag, *status;
- {
-
- if (lin[*i] == ch || lin[*i] == altch)
- {
- (*i)++;
- *flag = YES;
- }
- else
- *flag = NO;
-
- *status = OK;
- return (OK);
- }
-
-
- /* ckp --- check for "p" after command */
-
- int ckp (lin, i, pflag, status)
- char lin[];
- int i, *pflag, *status;
- {
-
- if (lin[i] == PRINT || lin[i] == UCPRINT)
- {
- i++;
- *pflag = YES;
- }
- else
- *pflag = NO;
-
- if (lin[i] == '\n')
- *status = OK;
- else
- *status = ERR;
-
- return (*status);
- }
-
-
- /* ckupd --- make sure it is ok to destroy the buffer */
-
- int ckupd (lin, i, cmd, status)
- char lin[], cmd;
- int *i, *status;
- {
- int flag;
- int ckchar ();
-
- *status = ckchar (ANYWAY, ANYWAY, lin, i, &flag, status);
- if (flag == NO && Buffer_changed == YES && Probation != cmd)
- {
- *status = ERR;
- Errcode = ESTUPID;
- Probation = cmd; /* if same command is repeated, */
- } /* we'll keep quiet */
-
- return (*status);
- }
-
-
- /* defalt --- set defaulted line numbers */
-
- defalt (def1, def2)
- int def1, def2;
- {
-
- if (Nlines == 0) /* no line numbers supplied, use defaults */
- {
- Line1 = def1;
- Line2 = def2;
- }
-
- return;
- }
-
-
- /* getfn --- get file name from lin[i]... */
-
- int getfn (lin, i, file)
- char lin[], file[];
- int i;
- {
- int j, k, ret;
-
- ret = ERR;
- if (lin[i + 1] == ' ')
- {
- j = i + 2; /* get new file name */
- SKIPBL (lin, j);
- for (k = 0; lin[j] != NEWLINE; k++, j++)
- file[k] = lin[j];
- file[k] = EOS;
- if (k > 0)
- ret = OK;
- }
- else if (lin[i + 1] == '\n' && Savfil[0] != EOS)
- {
- strcpy (file, Savfil); /* or old name */
- ret = OK;
- }
- else
- if (lin[i + 1] == '\n')
- Errcode = ENOFN;
- else
- Errcode = EFILEN;
-
- if (ret == OK && Savfil[1] == EOS)
- {
- strcpy (Savfil, file); /* save if no old one */
- mesg (Savfil, FILE_MSG);
- }
-
- return (ret);
- }
-
-
- /* getkn --- get mark name from lin[i], increment i */
-
- int getkn (lin, i, kname, dfltnm)
- char lin[], *kname, dfltnm;
- int *i;
- {
-
- if (lin[*i] == '\n' || lin[*i] == EOS)
- {
- *kname = dfltnm;
- return (EOF);
- }
-
- *kname = lin[*i];
- (*i)++;
- return (OK);
- }
-
-
- /* getrange --- get 'from' range for tlit command */
-
- int getrange (array, k, set, size, allbut)
- char array[], set[];
- int *k, size, *allbut;
- {
- int i, j;
- int addset ();
-
- Errcode = EBADLIST; /* preset error code */
-
- i = *k + 1;
- if (array[i] == NOTINCCL) /* check for negated character class */
- {
- *allbut = YES;
- i++;
- }
- else
- *allbut = NO;
-
- j = 0;
- filset (array[*k], array, &i, set, &j, size);
- if (array[i] != array[*k])
- {
- set[0] = EOS;
- return (ERR);
- }
- if (set[0] == EOS)
- {
- Errcode = ENOLIST;
- return (ERR);
- }
- if (j > 0 && addset (EOS, set, &j, size) == NO)
- {
- set[0] = EOS;
- return (ERR);
- }
-
- *k = i;
- Errcode = EEGARB;
-
- return (OK);
- }
-
-
- /* getrhs --- get substitution string for 's' command */
-
- int getrhs (lin, i, sub, gflag)
- char lin[], sub[];
- int *i, *gflag;
- {
- static char Subs[MAXPAT] = ""; /* saved replacement pattern */
- int j, maksub ();
- /* saved replacement pattern char */
-
-
- Errcode = EBADSUB;
-
- if (lin[*i] == EOS) /* missing the middle delimeter */
- return (ERR);
-
- if (lin[*i + 1] == '%' && (lin[*i + 2] == lin[*i]
- || lin[*i + 2] == '\n'))
- {
- /*
- * s//%/ --- should mean do the same thing as I did last time, even
- * s//&/ --- if I deleted something. So we comment out these lines.
- *
- if (Subs[0] == EOS)
- {
- Errcode = ENOSUB;
- return (ERR);
- }
- */
- strcpy (sub, Subs);
- *i += 2;
- if (lin[*i] == '\n')
- {
- /* fix it up for pattern matching routines */
- lin[*i] = lin[*i - 2];
- lin[*i + 1] = '\n';
- lin[*i + 2] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else /* not using saved substitution pattern */
- {
- if (lin[*i + 1] == '\n')
- {
- /* missing the trailing delimiter */
- /* pattern was empty */
- lin[*i + 1] = lin[*i]; /* supply missing delimiter */
- lin[*i + 2] = '\n';
- lin[*i + 3] = EOS;
- Peekc = SKIP_RIGHT;
- /* return (ERR); /* this is the original action */
- }
- else
- {
- /* stuff in pattern, check end of line */
- for (j = *i; lin[j] != EOS; j++)
- ;
- j -= 2; /* j now points to char before '\n' */
-
- if (lin[j] == 'p' || lin[j] == 'P')
- {
- --j;
- if (lin[j] == GLOBAL || lin[j] == UCGLOBAL)
- {
- if (j >= *i + 1 && lin[j-1] == lin[*i]
- && (lin[j-2] != ESCAPE
- || lin[j-3] == ESCAPE))
- ; /* leave alone */
- else
- {
- /* \<delim>gp\n is pattern */
- /* supply trailing delim */
- j += 2; /* j at \n */
- lin[j] = lin[*i];
- lin[++j] = '\n';
- lin[++j] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else if (j >= *i + 1 && lin[j] == lin[*i] &&
- (lin[j-1] != ESCAPE
- || lin[j-2] == ESCAPE))
- ; /* leave alone */
- else
- {
- /* \<delim>p\n is pattern */
- /* supply trailing delim */
- j += 2;
- lin[j] = lin[*i];
- lin[++j] = '\n';
- lin[++j] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else if (lin[j] == GLOBAL || lin[j] == UCGLOBAL)
- {
- --j;
- if (j >= *i + 1 && lin[j] == lin[*i] &&
- (lin[j-1] != ESCAPE
- || lin[j-2] == ESCAPE))
- ; /* leave alone */
- else
- {
- /* \<delim>g\n is pattern */
- /* supply trailing delim */
- j += 2; /* j at \n */
- lin[j] = lin[*i];
- lin[++j] = '\n';
- lin[++j] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else if ((lin[j] != lin[*i]) ||
- (lin[j] == lin[*i] &&
- lin[j-1] == ESCAPE && lin[j-2] != ESCAPE))
- {
- /* simply missing trailing delimeter */
- /* supply it */
- j++; /* j at \n */
- lin[j] = lin[*i];
- lin[++j] = '\n';
- lin[++j] = EOS;
- Peekc = SKIP_RIGHT;
- }
- /* else
- unescaped delim is there,
- leave well enough alone */
- }
-
- if ((*i = maksub (lin, *i + 1, lin[*i], sub)) == ERR)
- return (ERR);
-
- strcpy (Subs, sub); /* save pattern for later */
- }
-
- if (lin[*i + 1] == GLOBAL || lin[*i + 1] == UCGLOBAL)
- {
- (*i)++;
- *gflag = YES;
- }
- else
- *gflag = NO;
-
- Errcode = EEGARB; /* the default */
-
- return (OK);
-
- }
-
-
- /* getstr --- get string from lin at i, copy to dst, bump i */
-
- /*
- ** NOTE: this routine only called for doing the join command.
- ** therefore, don't do anything else with it.
- */
-
- int getstr (lin, i, dst, maxdst)
- char lin[], dst[];
- int *i, maxdst;
- {
- char delim;
- char esc ();
- int j, k, d;
-
- j = *i;
- Errcode = EBADSTR;
-
- delim = lin[j];
-
- if (delim == '\n')
- {
- lin[j] = '/';
- lin[++j] = ' '; /* join with a single blank */
- lin[++j] = '/';
- lin[++j] = '\n';
- lin[++j] = EOS;
- j = *i;
- delim = lin[j];
- Peekc = SKIP_RIGHT;
- /* now fall thru */
-
- /* return (ERR); /* old way */
- }
- else if ((delim == 'p' || delim == 'P') && lin[j + 1] == '\n') /* jp */
- {
- lin[j] = '/';
- lin[++j] = ' '; /* join with a single blank */
- lin[++j] = '/';
- lin[++j] = delim; /* 'p' or 'P' */
- lin[++j] = '\n';
- lin[++j] = EOS;
- j = *i;
- delim = lin[j];
- Peekc = SKIP_RIGHT;
- /* now fall thru */
- }
-
- if (lin[j + 1] == '\n') /* command was 'j/' */
- {
- dst[0] = EOS;
- Errcode = ENOERR;
- return (OK);
- /* return (ERR); /* old way */
- }
-
- /*
- * otherwise, stuff there in the string, try to allow for
- * a missing final delimiter.
- */
-
- for (k = j + 1; lin[k] != '\n'; k++)
- ; /* find end */
-
- k--; /* now points to char before newline */
-
- if (lin[k] == 'p' || lin[k] == 'P')
- {
- k--;
- if (lin[k] == delim &&
- (lin[k-1] != ESCAPE || lin[k-2] == ESCAPE))
- ; /* it's fine, leave it alone */
- else
- {
- /* ESCAPE delim p NEWLINE is the join string */
- /* supply trailing delimiter. */
- k += 2;
- lin[k] = delim;
- lin[++k] = '\n';
- lin[++k] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else if (lin[k] != delim || (lin[k-1] == ESCAPE && lin[k-2] != ESCAPE))
- {
- /* no delim and no p, or last char is escaped delim */
- k++;
- lin[k] = delim;
- lin[++k] = '\n';
- lin[++k] = EOS;
- Peekc = SKIP_RIGHT;
- }
- /* else
- delim is there
- leave well enough alone */
-
- /* code to actually do the join */
-
- for (k = j + 1; lin[k] != delim; k++) /* find end */
- {
- if (lin[k] == '\n' || lin[k] == EOS)
- if (delim == ' ')
- break;
- else
- return (ERR);
- esc (lin, &k);
- }
- if (k - j > maxdst)
- return (ERR);
-
- for (d = 0, j++; j < k; d++, j++)
- dst[d] = esc (lin, &j);
- dst[d] = EOS;
-
- *i = j;
- Errcode = EEGARB; /* the default */
-
- return (OK);
- }
-
-
- /* getwrd --- get next word from line at i; increment i */
-
- int getwrd (line, i, word, size)
- char line[], word[];
- int *i, size;
- {
- int j;
-
- SKIPBL (line, *i);
- j = 0;
- while (line[*i] != ' ' && line[*i] != '\n' && line[*i] != EOS)
- {
- if (j < size - 1)
- {
- word[j] = line[*i];
- j++;
- }
- (*i)++;
- }
- word[j] = EOS;
-
- return (j);
- }
-
-
- /* knscan --- scan for a line with a given mark name */
-
- int knscan (way, num)
- int way, *num;
- {
- int nextln ();
- LINEDESC *k;
- LINEDESC *getind ();
-
- *num = Curln;
- k = getind (*num);
- do {
- bump (num, &k, way);
- if (k -> Markname == Savknm)
- return (OK);
- } while (*num != Curln && ! intrpt ());
-
- if (Errcode = EEGARB)
- Errcode = EKNOTFND;
- return (ERR);
-
- }
-
-
- /* makset --- make set from array[k] in set */
-
- int makset (array, k, set, size)
- char array[], set[];
- int *k, size;
- {
- static char Tset[MAXPAT] = ""; /* saved translit dest range */
- int i, j;
- int l;
- int addset ();
-
- Errcode = EBADLIST;
-
- /*
- * try to allow missing delimiter for translit command.
- */
-
- if (array[*k] == EOS)
- return (ERR);
-
- if (array[*k + 1] == '%' && (array[*k + 2] == array[*k]
- || array[*k + 2] == '\n'))
- {
- strcpy (set, Tset);
- *k += 2;
- if (array[*k] == '\n')
- {
- /* fix it up for rest of the routines */
- array[*k] = array[*k - 2];
- array[*k+ 1] = '\n';
- array[*k+ 2] = EOS;
- }
- Peekc = SKIP_RIGHT;
- }
- else
- {
-
- for (l = *k; array[l] != EOS; l++)
- ;
- l -= 2; /* l now points to char before '\n' */
-
- if (l == *k) /* "y/.../\n" */
- {
- array[*k + 1] = array[*k]; /* add delimiter */
- array[*k + 2] = '\n';
- array[*k + 3] = EOS;
- Peekc = SKIP_RIGHT;
- }
- else if (array[l] == 'p' || array[l] == 'P')
- {
- --l;
- if (l >= *k + 1 && array[l] == array[*k] &&
- (array[l-1] != ESCAPE || array[l-2] == ESCAPE))
- ; /* leave alone */
- else
- {
- /* \<delim>p\n is set */
- /* supply trailing delim */
- l += 2;
- array[l] = array[*k];
- array[++l] = '\n';
- array[++l] = EOS;
- Peekc = SKIP_RIGHT;
- }
- }
- else if (array[l] != array[*k] /* no delim, and no p */
- || (array[l-1] == ESCAPE /* or last char is escaped delim */
- && array[l-2] != ESCAPE))
- {
- /* simply missing trailing delimeter */
- /* supply it */
- l++; /* l now at \n */
- array[l] = array[*k];
- array[++l] = '\n';
- array[++l] = EOS;
- Peekc = SKIP_RIGHT;
- }
- /* else
- delim is there,
- leave well enough alone */
-
- j = 0;
- i = *k + 1;
- filset (array[*k], array, &i, set, &j, size);
-
- if (array[i] != array[*k])
- return (ERR);
-
- if (addset (EOS, set, &j, size) == NO)
- return (ERR);
-
- strcpy (Tset, set); /* save for later */
- *k = i;
-
- }
-
- Errcode = EEGARB;
-
- return (OK);
- }
-
-
- /* optpat --- make pattern specified at lin[i] */
-
- int optpat (lin, i)
- char lin[];
- int *i;
- {
- int makpat ();
-
- if (lin[*i] == EOS)
- *i = ERR;
- else if (lin[*i + 1] == EOS)
- *i = ERR;
- else if (lin[*i + 1] == lin[*i]) /* repeated delimiter */
- (*i)++; /* leave existing pattern alone */
- else
- *i = makpat (lin, *i + 1, lin[*i], Pat);
-
- if (Pat [0] == EOS)
- {
- Errcode = ENOPAT;
- return (ERR);
- }
- if (*i == ERR)
- {
- Pat[0] = EOS;
- Errcode = EBADPAT;
- return (ERR);
- }
- return (OK);
- }
-
-
- /* ptscan --- scan for next occurrence of pattern */
-
- int ptscan (way, num)
- int way, *num;
- {
- LINEDESC *getind ();
- LINEDESC *k;
- int match ();
-
- *num = Curln;
- k = getind (*num);
- do {
- bump (num, &k, way);
- gtxt (k);
- if (match (Txt, Pat) == YES)
- return (OK);
- } while (*num != Curln && ! intrpt ());
-
- if (Errcode == EEGARB)
- Errcode = EPNOTFND;
-
- return (ERR);
- }
-
-
- /* settab --- set tab stops */
-
- int settab (str)
- char str[];
- {
- int i, j, n, maxstop, last, inc, ret;
- int ctoi ();
-
- for (i = 0; i < MAXLINE; i++) /* clear all tab stops */
- Tabstops[i] = NO;
-
- ret = OK;
- maxstop = 0;
- last = 1;
-
- i = 0;
- SKIPBL (str, i);
- while (str[i] != EOS && str[i] != '\n')
- {
- if (str[i] == '+') /* increment */
- {
- i++;
- inc = YES;
- }
- else
- inc = NO;
-
- n = ctoi (str, &i);
-
- if (n <= 0 || n >= MAXLINE)
- {
- ret = ERR;
- Errcode = ENONSENSE;
- break;
- }
-
- if (str[i] != ' ' && str[i] != '+' &&
- str[i] != '\n' && str[i] != EOS)
- {
- ret = ERR;
- Errcode = EBADTABS;
- break;
- }
-
- if (inc == YES)
- {
- for (j = last + n; j < MAXLINE; j += n)
- {
- Tabstops[j - 1] = YES;
- maxstop = max (j, maxstop);
- }
- }
- else
- {
- Tabstops[n - 1] = YES;
- last = n;
- maxstop = max (n, maxstop);
- }
- SKIPBL (str, i);
- } /* while ... */
-
- if (ret == ERR)
- maxstop = 0;
-
- if (maxstop == 0) /* no tab stops specified, use defaults */
- {
- for (i = 4; i < MAXLINE - 1; i += 4)
- Tabstops[i] = YES;
- maxstop = i - 4 + 1;
- }
-
- Tabstops[0] = YES; /* always set to YES */
-
- for (i = maxstop; i < MAXLINE; i++)
- Tabstops[i] = YES;
-
- return (ret);
- }
-
- /* serc --- read in ./.serc or $HOME/.serc and execute the commands in it. */
-
- /*
- * note that se's special control characters are NOT processed,
- * and therefore should NOT be used in one's .serc file.
- */
-
- static serc ()
- {
- char file[MAXLINE];
- char lin[MAXLINE];
- char *expand_env ();
- FILE *fp;
- int status = ENOERR;
- int len, cursav;
-
- strcpy (file, expand_env ("$HOME/.serc"));
-
- if ((fp = fopen ("./.serc", "r")) == NULL ||
- (fp = fopen (file, "r")) == NULL)
- return;
-
- while (fgets (lin, sizeof lin, fp) != NULL && status != EOF /*??*/)
- {
- if (lin[0] == '#' || lin[0] == '\n')
- continue; /* comment in .serc file */
-
- /* most of this code stolen from edit() */
- len = 0;
- cursav = Curln;
- if (getlst (lin, &len, &status) == OK)
- {
- if (ckglob (lin, &len, &status) == OK)
- doglob (lin, &len, &cursav, &status);
- else if (status != ERR)
- docmd (lin, len, NO, &status);
- }
- if (status == ERR)
- {
- if (Errcode == EHANGUP)
- hangup ();
- Curln = min (cursav, Lastln);
- }
- }
- fclose (fp);
- }
-
- #ifdef LOG_USAGE
-
- /* log -- log se usage */
-
-
- static log ()
- {
- static char logfile[] = "/usr/tmp/se.log"; /* a public file */
- char logname[MAXLINE], tod[26]; /* tod => time of day */
- long clock;
- FILE *fp;
- char *ctime ();
- long time ();
- int old_umask;
- #ifdef BSD
- char *getlogin ();
- #else
- char *cuserid ();
- #endif
-
- /* get the login name */
- #ifdef BSD
- strcpy (logname, getlogin ());
- #else
- cuserid (logname);
- #endif
-
- time (&clock);
- strcpy (tod, ctime (&clock)); /* see the manual on ctime(3C) */
- tod[24] = EOS; /* delete the '\n' at the end */
-
- old_umask = umask (0); /* allow writes for everyone */
- /* when first call creates the file */
-
- if ((fp = fopen (logfile, "a")) != NULL)
- {
- /* all ok, write out statistics */
- fprintf (fp, "%s used se on %s.\n", logname, tod);
- fclose (fp);
- }
- /* else
- don't do anything */
-
- umask (old_umask);
-
- }
- #endif
-
- /* sysname --- return a string telling us who we are */
-
- #ifdef USG
- #include <sys/utsname.h> /* stuff to find out who we are */
- #endif
-
- char *sysname ()
- {
- int i, j, k;
- char c;
- static char buf[MAXLINE] = "";
- FILE *fp;
- static char unknown[] = "unknown";
-
- #ifdef USG /* System V */
- static struct utsname whoarewe;
-
- uname (& whoarewe);
- return (whoarewe.nodename);
- #else
- #ifdef BSD4_2 /* Berkeley 4.2 */
- if (buf[0] != EOS)
- return (buf);
-
- j = sizeof (buf);
- k = gethostname (buf, & j);
- if (k != 0)
- return (unknown);
- else
- return (buf);
- #else /* Berkeley 4.1 */
- if (buf[0] != EOS)
- return (buf);
-
- if ((fp = fopen ("/usr/include/whoami.h", "r")) == NULL)
- return (unknown);
- else
- {
- auto char *cp;
- /*
- * file should contain a single line:
- * #define sysname "......"
- */
- while ((c = getc (fp)) != '"' && c != EOF)
- ;
- if (c == EOF)
- cp = unknown;
- else
- {
- for (i = 0; (c = getc (fp)) != '"' && c != EOF; i++)
- buf[i] = c;
- buf[i] = EOS;
- if (c == EOF && i == 0)
- cp = unknown;
- else
- cp = buf;
- }
- fclose (fp);
- return (cp);
- }
- #endif
- #endif
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'extern.h'" '(4770 characters)'
- if test -f 'extern.h'
- then
- echo shar: will not over-write existing file "'extern.h'"
- else
- cat << \SHAR_EOF > 'extern.h'
- /*
- * $Header: extern.h,v 1.2 86/07/14 16:44:30 arnold Exp $
- */
-
- /*
- * $Log: extern.h,v $
- * Revision 1.2 86/07/14 16:44:30 arnold
- * Removed stuff that was Georgia Tech specific.
- *
- * Revision 1.1 86/05/06 13:36:05 osadr
- * Initial revision
- *
- *
- */
-
- /*
- ** extern.h
- **
- ** external data definitions
- ** for the screen editor
- */
-
- /* Concerning line numbers: */
- extern int Line1; /* first line number on command */
- extern int Line2; /* second line number on command */
- extern int Nlines; /* number of line numbers specified */
- extern int Curln; /* current line; value of dot */
- extern int Lastln; /* last line; value of dollar */
-
-
- /* Concerning patterns: */
- extern char Pat[MAXPAT]; /* saved pattern */
-
-
- /* Concerning the text of lines: */
- extern char Txt[MAXLINE]; /* text of current line */
-
-
- /* Concerning file names: */
- extern char Savfil[MAXLINE]; /* remembered file name */
-
-
- /* Concerning line descriptors: */
- extern LINEDESC Buf[MAXBUF];
- #ifdef OLD_SCRATCH
- extern LINEDESC *Lastbf; /* last pointer used in Buf */
- extern LINEDESC *Free; /* head of free list */
- #endif
- extern LINEDESC *Line0; /* head of list of line descriptors */
-
-
- /* Concerning the 'undo' command: */
- extern LINEDESC *Limbo; /* head of limbo list for undo */
- extern int Limcnt; /* number of lines in limbo list */
-
-
- /* Concerning the scratch file: */
- extern filedes Scr; /* scratch file descriptor */
- extern unsigned Scrend; /* end of info on scratch file */
- extern char Scrname[MAXLINE]; /* name of scratch file */
- extern int Lost_lines; /* number of garbage lines in scratch file */
-
-
- /* Concerning miscellaneous variables */
- extern int Buffer_changed; /* YES if buffer changed since last write */
- extern int Errcode; /* cause of most recent error */
- extern int Saverrcode; /* cause of previous error */
- extern int Probation; /* YES if unsaved buffer can be destroyed */
- extern int Argno; /* command line argument pointer */
- extern char Last_char_scanned; /* last char scanned with ctl-s or -l */
- #ifdef HARD_TERMS
- extern int Tspeed; /* terminal speed in characters/second */
- #endif
- extern char Peekc; /* push a SKIP_RIGHT if adding delimiters */
- #ifdef BSD4_2
- extern int Reading; /* are we doing terminal input? */
- #endif
-
-
- /* Concerning options: */
- extern int Tabstops[MAXLINE]; /* array of tab stops */
- extern char Unprintable; /* char to print for unprintable chars */
- extern int Absnos; /* use absolute numbers in margin */
- extern int Nchoise; /* choice of line number for cont. display */
- extern int Overlay_col; /* initial cursor column for 'v' command */
- extern int Warncol; /* where to turn on column warning */
- extern int Firstcol; /* leftmost column to display */
- extern int Indent; /* indent col; 0=same as previous line */
- extern int Notify; /* notify user if he has mail in mail file */
- extern int Globals; /* substitutes in a global don't fail */
- extern int No_hardware; /* never use hardware insert/delete */
-
-
- #ifdef HARD_TERMS
- /* Concerning the terminal type */
- extern int Term_type; /* terminal type */
- #endif
-
-
- /* Concerning the screen format: */
- extern char Screen_image[MAXROWS][MAXCOLS];
- extern char Msgalloc[MAXCOLS]; /* column allocation of status line */
- extern int Nrows; /* number of rows on screen */
- extern int Ncols; /* number of columns on screen */
- extern int Currow; /* vertical cursor coordinate */
- extern int Curcol; /* horizontal cursor coordinate */
- extern int Toprow; /* top row of window field on screen */
- extern int Botrow; /* bottom row of window field on screen */
- extern int Cmdrow; /* row number of command line */
- extern int Topln; /* line number of first line on screen */
- extern int Insert_mode; /* flag to specify character insertion */
- extern int Invert_case; /* flag to specify case mapping on input */
- extern int First_affected; /* number of first line affected by cmd */
- extern int Rel_a; /* char to use for first alpha line number */
- extern int Rel_z; /* char to use for last alpha line number */
- extern int Scline[MAXROWS]; /* lines currently on screen (rel to Sctop) */
- extern int Sctop; /* first line currently on screen */
- extern int Sclen; /* number of lines currently on screen */
- extern char Blanks[MAXCOLS]; /* all blanks for filling in lines on screen */
- extern char Tobuf[MAXTOBUF]; /* buffer for collecting terminal output */
- extern char *Tobp; /* pointer to last used part of Tobuf */
-
-
- /* Concerning interrupts: */
- extern int Int_caught; /* caught a SIGINT from user */
- extern int Hup_caught; /* caught a SIGHUP when phone line dropped */
- #ifdef SIGTSTP
- extern int Catching_stops; /* catching or ignoring SIGTSTP's? */
- #endif
-
- /* Concerning file encryption: */
- extern int Crypting; /* doing file encryption? */
- extern char Key[KEYSIZE]; /* encryption key */
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'m4munge'" '(704 characters)'
- if test -f 'm4munge'
- then
- echo shar: will not over-write existing file "'m4munge'"
- else
- cat << \SHAR_EOF > 'm4munge'
- #! /bin/sh
- # m4munge --- take what the 'where' command produces, and change it for m4
- #
- # $Header: m4munge,v 1.2 86/07/11 15:13:56 osadr Exp $
- #
- # $Log: m4munge,v $
- # Revision 1.2 86/07/11 15:13:56 osadr
- # Removed Georgia Tech specific items.
- #
- # Revision 1.1 86/05/06 13:35:02 osadr
- # Initial revision
- #
- #
- #
-
- for i in $*
- do
- case $i in
- -DUSG) echo 'define(USG,YES)' ;;
- -UUSG) echo 'define(USG,NO)' ;;
- -DBSD) echo 'define(BSD,YES)' ;;
- -UBSD) echo 'define(BSD,NO)' ;;
- -DBSD4_2) echo 'define(BSD4_2,YES)' ;;
- -UBSD4_2) echo 'define(BSD4_2,NO)' ;;
- -DS5R2) echo 'define(S5R2,YES)' ;;
- -US5R2) echo 'define(S5R2,NO)' ;;
- -DHARD_TERMS) echo 'define(HARD_TERMS,YES)' ;;
- esac
- done
- SHAR_EOF
- chmod +x 'm4munge'
- fi # end of overwriting check
- echo shar: extracting "'main.c'" '(13208 characters)'
- if test -f 'main.c'
- then
- echo shar: will not over-write existing file "'main.c'"
- else
- cat << \SHAR_EOF > 'main.c'
- #ifndef lint
- static char RCSid[] = "$Header: main.c,v 1.4 86/10/07 14:50:17 arnold Exp $";
- #endif
-
- /*
- * $Log: main.c,v $
- * Revision 1.4 86/10/07 14:50:17 arnold
- * Changed setterm to set_term, to avoid Unix/PC shared library conflict.
- *
- * Revision 1.3 86/07/17 17:20:58 arnold
- * Terminal initialization code cleaned up considerably.
- *
- * Revision 1.2 86/07/11 15:12:26 osadr
- * Removed code that was Georgia Tech specific
- *
- * Revision 1.1 86/05/06 13:37:38 osadr
- * Initial revision
- *
- *
- */
-
- /*
- ** main.c
- **
- ** main program and lots of other routines
- ** for the se screen editor.
- */
-
- #include "se.h"
-
- /* declare global variables */
-
- /* Concerning line numbers: */
- int Line1; /* first line number on command */
- int Line2; /* second line number on command */
- int Nlines; /* number of line numbers specified */
- int Curln; /* current line; value of dot */
- int Lastln; /* last line; value of dollar */
-
-
- /* Concerning patterns: */
- char Pat[MAXPAT] = ""; /* saved pattern */
-
-
- /* Concerning the text of lines: */
- char Txt[MAXLINE]; /* text of current line */
-
-
- /* Concerning file names: */
- char Savfil[MAXLINE] = ""; /* remembered file name */
-
-
- /* Concerning line descriptors: */
- LINEDESC Buf[MAXBUF];
- LINEDESC *Line0; /* head of list of line descriptors */
- #ifdef OLD_SCRATCH
- LINEDESC *Lastbf; /* last pointer used in Buf */
- LINEDESC *Free; /* head of free list */
- #endif
-
-
- /* Concerning the 'undo' command: */
- LINEDESC *Limbo; /* head of limbo list for undo */
- int Limcnt; /* number of lines in limbo list */
-
-
- /* Concerning the scratch file: */
- filedes Scr; /* scratch file descriptor */
- unsigned Scrend; /* end of info on scratch file */
- char Scrname[MAXLINE]; /* name of scratch file */
- int Lost_lines; /* number of garbage lines in scratch file */
-
-
- /* Concerning miscellaneous variables */
- int Buffer_changed = NO;/* YES if buffer changed since last write */
- int Errcode = ENOERR; /* cause of most recent error */
- int Saverrcode = ENOERR;/* cause of previous error */
- int Probation = NO; /* YES if unsaved buffer can be destroyed */
- int Argno; /* command line argument pointer */
- char Last_char_scanned = 0; /* last char scanned w/ctl-[sl], init illegal */
- char Peekc = EOS; /* push a SKIP_RIGHT if adding delimiters */
- #ifdef HARD_TERMS
- int Tspeed; /* terminal speed in characters/second */
- #endif
- #ifdef BSD4_2
- int Reading = NO; /* are we doing terminal input? */
- #endif
-
-
- /* Concerning options: */
- int Tabstops[MAXLINE]; /* array of tab stops */
- char Unprintable = ' '; /* char to print for unprintable chars */
- int Absnos = NO; /* use absolute numbers in margin */
- int Nchoise = EOS; /* choice of line number for cont. display */
- int Overlay_col = 0; /* initial cursor column for 'v' command */
- int Warncol; /* where to turn on column warning, set in dosopt() */
- int Firstcol = 0; /* leftmost column to display */
- int Indent = 1; /* indent col; 0=same as previous line */
- int Notify = YES; /* notify user if he has mail in mail file */
- int Globals = NO; /* substitutes in a global don't fail */
- int No_hardware; /* never use hardware insert/delete */
-
-
- #ifdef HARD_TERMS
- /* Concerning the terminal type */
- int Term_type; /* terminal type */
- #endif
-
-
- /* Concerning the screen format: */
- char Screen_image[MAXROWS][MAXCOLS];
- char Msgalloc[MAXCOLS]; /* column allocation of status line */
- int Nrows; /* number of rows on screen */
- int Ncols; /* number of columns on screen */
- int Currow; /* vertical cursor coordinate */
- int Curcol; /* horizontal cursor coordinate */
- int Toprow; /* top row of window field on screen */
- int Botrow; /* bottom row of window field on screen */
- int Cmdrow; /* row number of command line */
- int Topln; /* line number of first line on screen */
- int Insert_mode; /* flag to specify character insertion */
- int Invert_case; /* flag to specify case mapping on input */
- int First_affected; /* number of first line affected by cmd */
- int Rel_a; /* char to use for first alpha line number */
- int Rel_z; /* char to use for last alpha line number */
- int Scline[MAXROWS]; /* lines currently on screen (rel to Sctop) */
- int Sctop; /* first line currently on screen */
- int Sclen; /* number of lines currently on screen */
- char Blanks[MAXCOLS]; /* all blanks for filling in lines on screen */
- char Tobuf[MAXTOBUF]; /* buffer for collecting terminal output */
- char *Tobp = Tobuf - 1; /* pointer to last used part of Tobuf */
-
-
- /* Concerning interrupts: */
- int Int_caught = 0; /* caught a SIGINT from user */
- int Hup_caught = 0; /* caught a SIGHUP when phone line dropped */
- #ifdef BSD
- int Catching_stops; /* catching or ignoring SIGTSTP's? */
- #endif
-
- /* Concerning file encryption: */
- int Crypting = NO; /* doing file encryption? */
- char Key[KEYSIZE] = ""; /* saved encryption key */
-
- extern char *getenv ();
-
- /* main --- main program for screen editor */
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
- char *basename ();
- int int_hdlr (), hup_hdlr ();
- int (*old_int)(), (*old_quit)();
- #ifdef BSD
- int stop_hdlr (), (*old_stop)();
- #endif
- /* catch quit and hangup signals */
- /*
- * In the terminal driver munging routines, we set Control-P
- * to generate an interrupt, and turn off generating Quits from
- * the terminal. Now we just ignore them if sent from elsewhere.
- */
-
- signal (SIGHUP, hup_hdlr);
-
- old_int = signal (SIGINT, int_hdlr);
- old_quit = signal (SIGQUIT, SIG_IGN);
-
- #ifdef notdef
- /*
- * This is commented out so that se can be run from the news
- * software. Commenting it out will also allow you to put it
- * in the background, which could give you trouble. So beware.
- */
-
- if (old_int == SIG_IGN || old_quit == SIG_IGN)
- {
- /* fired off into the background, refuse to run */
- if (isatty (fileno (stdin)))
- {
- fprintf (stderr, "%s: I refuse to run in the background.\n",
- basename (argv[0]));
- exit (2);
- }
- /* else
- assume input is a script */
- }
- #endif
-
- #ifdef BSD
- old_stop = signal (SIGTSTP, stop_hdlr);
-
- if (old_stop == SIG_IGN) /* running bourne shell */
- {
- signal (SIGTSTP, SIG_IGN); /* restore it */
- Catching_stops = NO;
- }
- else
- Catching_stops = YES;
- /* running C-shell or BRL sh, catch Control-Z's */
- #endif
-
- /* set terminal to no echo, no output processing, break enabled */
- ttyedit ();
-
- #ifdef HARD_TERMS
- Tspeed = getspeed (1); /* speed of stdout */
- #endif
-
- initialize (argc, argv);
-
- edit (argc, argv);
-
- #ifndef HARD_TERMS
- t_exit ();
- #endif
-
- /* reset the terminal mode */
- ttynormal ();
- }
-
- /* error --- print error message and die semi-gracefully */
-
- error (coredump, msg)
- int coredump;
- char *msg;
- {
- /*
- * You might think we want to try and save the buffer,
- * BUT, fatal errors can be caused by buffer problems,
- * which would end up putting us into a non-ending recursion.
- */
-
- ttynormal ();
- fprintf (stderr, "%s\n", msg);
- signal (SIGQUIT, SIG_DFL); /* restore normal quit handling */
- if (coredump)
- kill (getpid (), SIGQUIT); /* dump memory */
- else
- exit (1);
- }
-
- /* initialize --- set up global data areas, get terminal type */
-
- initialize (argc, argv)
- int argc;
- char *argv[];
- {
- int i, dosopt ();
-
- Argno = 1;
- #ifdef HARD_TERMS
- /* Determine what type of terminal we're on */
- if (Argno < argc && argv[Argno][0] == '-' && argv[Argno][2] == EOS
- && (argv[Argno][1] == 't' || argv[Argno][1] == 'T'))
- {
- Argno = 2;
- if (Argno < argc)
- {
- strmap (argv[Argno], 'l');
- if (set_term (argv[Argno]) == ERR)
- usage ();
- else
- Argno++;
- }
- else
- usage ();
- }
- else
- /* fall through to the if, below */
- #endif
- if (set_term (getenv ("TERM")) == ERR)
- usage ();
-
- /* Initialize the scratch file: */
- mkbuf ();
-
- /* Initialize screen format parameters: */
- setscreen ();
-
- /* Initialize the array of blanks to blanks */
- for (i = 0; i < Ncols; i++)
- Blanks[i] = ' ';
- Blanks[i] = '\0';
-
- if (dosopt ("") == ERR)
- error ("in initialize: can't happen");
- }
-
- /* intrpt --- see if there has been an interrupt or hangup */
-
- int intrpt ()
- {
- if (Int_caught)
- {
- Errcode = EBREAK;
- Int_caught = 0;
- return (1);
- }
- else if (Hup_caught)
- {
- Errcode = EHANGUP;
- Hup_caught = 0;
- return (1);
- }
- return (0);
- }
-
- /* int_hdlr --- handle an interrupt signal */
-
- int_hdlr ()
- {
- #ifndef BSD4_2
- signal (SIGINT, int_hdlr);
- #endif
- Int_caught = 1;
- }
-
- /* hup_hdlr --- handle a hangup signal */
-
- hup_hdlr ()
- {
- #ifndef BSD4_2
- signal (SIGHUP, hup_hdlr);
- Hup_caught = 1;
- #else
- /* do things different cause of 4.2 (sigh) */
- Hup_caught = 1;
- if (Reading) /* doing tty i/o, and that is where hup came from */
- hangup ();
- #endif
- }
-
- #ifdef BSD
- /* stop_hdlr --- handle the berkeley stop/suspend signal */
-
- int stop_hdlr ()
- {
- clrscreen ();
- tflush ();
- ttynormal ();
- #ifdef BSD4_2
- /* this handler remains in effect, use uncatchable signal */
- kill (getpid(), SIGSTOP);
- #else
- /* action was reset to default when we caught it */
- kill (getpid(), SIGTSTP);
- #endif
- /*
- * user does a "fg"
- */
- #ifndef BSD4_2
- signal (SIGTSTP, stop_hdlr); /* reset stop catching */
- #endif
- ttyedit ();
- restore_screen ();
- }
- #endif
-
- /* hangup --- dump contents of edit buffer if SIGHUP occurs */
-
- hangup ()
- {
- /* close terminal to avoid hanging on any accidental I/O: */
- close (0);
- close (1);
- close (2);
-
- signal (SIGHUP, SIG_IGN);
- signal (SIGINT, SIG_IGN);
- signal (SIGQUIT, SIG_IGN);
- Hup_caught = 0;
- Crypting = NO; /* force buffer to be clear text */
- dowrit (1, Lastln, "se.hangup", NO, YES, NO);
- clrbuf ();
- exit (1);
- }
-
- /* mswait --- message waiting subroutine */
-
- /* if the user wants to be notified, and the mail file is readable, */
- /* and there is something in it, then he is given the message. */
- /* the om command toggles Notify, controlling notification. */
-
- #include <sys/types.h>
- #include <sys/stat.h>
-
- mswait ()
- {
- int access ();
- struct stat buf;
- static char *mbox = NULL;
- static int first = YES;
- static unsigned long mtime = 0L;
-
- if (! Notify)
- return;
-
- if (first)
- {
- first = NO;
- if ((mbox = getenv ("MAIL")) != NULL && access (mbox, 4) == 0)
- {
- if (stat (mbox, &buf) >= 0)
- {
- mtime = buf.st_mtime;
- if (buf.st_size > 0)
- remark ("You have mail");
- }
- }
- }
- else if (mbox && stat (mbox, &buf) >= 0 && buf.st_mtime > mtime)
- {
- mtime = buf.st_mtime;
- remark ("You have new mail");
- twrite (1, "\007", 1); /* Bell */
- }
- }
-
- /* printverboseerrormessage --- print verbose error message */
-
- printverboseerrormessage ()
- {
- switch (Errcode) {
- case EBACKWARD:
- remark ("Line numbers in backward order");
- break;
- case ENOPAT:
- remark ("No saved pattern -- sorry");
- break;
- case EBADPAT:
- remark ("Bad syntax in pattern");
- break;
- case EBADSTR:
- remark ("Bad syntax in string parameter");
- break;
- case EBADSUB:
- remark ("Bad syntax in substitution string");
- break;
- case ECANTREAD:
- remark ("File is not readable");
- break;
- case EEGARB:
- remark ("Garbage after your command");
- break;
- case EFILEN:
- remark ("Bad syntax in file name");
- break;
- case EBADTABS:
- remark ("Bad tabstop syntax");
- break;
- case EINSIDEOUT:
- remark ("Can't move a group into itself");
- break;
- case EKNOTFND:
- remark ("No line has that mark name");
- break;
- case ELINE1:
- remark ("");
- break;
- case E2LONG:
- remark ("Resultant line too long to handle");
- break;
- case ENOERR:
- remark ("No error to report");
- break;
- case ENOLIMBO:
- remark ("No lines in limbo");
- break;
- case EODLSSGTR:
- remark ("Expected '<', '>', or nothing after 'od'");
- break;
- case EORANGE:
- remark ("Line number out of range");
- break;
- case EOWHAT:
- remark ("Can't recognize option");
- break;
- case EPNOTFND:
- remark ("No line contains that pattern");
- break;
- case ESTUPID:
- remark ("Buffer hasn't been saved");
- break;
- case EWHATZAT:
- remark ("No command recognized");
- break;
- case EBREAK:
- remark ("You interrupted me");
- break;
- case ELINE2:
- remark ("Last line number beyond end of file");
- break;
- case ECANTWRITE:
- remark ("File is not writeable");
- break;
- case ECANTINJECT:
- remark ("No room for any more lines!");
- break;
- case ENOMATCH:
- remark ("No match for pattern");
- break;
- case ENOFN:
- remark ("No saved filename");
- break;
- case EBADLIST:
- remark ("Bad syntax in character list");
- break;
- case ENOLIST:
- remark ("No saved character list -- sorry");
- break;
- case ENONSENSE:
- remark ("Unreasonable value");
- break;
- case ENOHELP:
- remark ("No help available");
- break;
- case EBADLNR:
- remark ("Line numbers not allowed");
- break;
- case EFEXISTS:
- remark ("File already exists");
- break;
- case EBADCOL:
- remark ("Improper column number specification");
- break;
- case ENOLANG:
- remark ("Unknown source language");
- break;
- case ETRUNC:
- remark ("Lines were truncated");
- break;
- case ENOSHELL:
- remark ("Type control-q to rebuild screen");
- break;
- case ECANTFORK:
- remark ("Can't fork --- get help!");
- break;
- case ENOSUB:
- remark ("No saved replacement --- sorry");
- break;
- case ENOCMD:
- remark ("No saved shell command --- sorry");
- break;
- default:
- remark ("?");
- break;
- }
- Errcode = ENOERR;
- }
-
- /* usage --- print usage diagnostic and die */
-
- usage ()
- {
- ttynormal ();
- fprintf (stderr, "Usage: se%s%s\n",
- #ifdef HARD_TERMS
- " [ -t <terminal> ] ",
- #else
- " ",
- #endif
- "[ --acdfghiklmstuvwxyz ] [ file ... ]");
- exit (1);
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'makefile'" '(3680 characters)'
- if test -f 'makefile'
- then
- echo shar: will not over-write existing file "'makefile'"
- else
- cat << \SHAR_EOF > 'makefile'
- #
- # $Header: makefile,v 1.3 86/09/19 12:16:19 arnold Exp $
- #
- # $Log: makefile,v $
- # Revision 1.3 86/09/19 12:16:19 arnold
- # Fixed to ignore return code from shell if statement.
- #
- # Revision 1.2 86/05/27 17:47:50 osadr
- # Changes to support the Unix PC (no egrep, shared library), and
- # to support making if . is not in the search path.
- #
- # Revision 1.1 86/05/06 13:39:18 osadr
- # Initial revision
- #
- #
- #
- # makefile for the Georgia Tech Screen Editor, 'se'
-
- HEADERS= ascii.h constdefs.h extern.h se.h
-
- SRCS= docmd1.c docmd2.c edit.c main.c misc.c scratch.c screen.c term.c
- OBJS= docmd1.o docmd2.o edit.o main.o misc.o scratch.o screen.o term.o
-
- LIBRARIES= libchangetty/libchangetty.a pat/libpat.a
-
- DOCS= makefile README
- MANS= scriptse.1 se.1
-
- CFLAGS= -O `cat flags`
- LDFLAGS=
-
- # On BSD systems, force make to use the right shell for commands
- SHELL=/bin/sh
-
- ###########################################################################
- # Begin system dependant macro definitions
-
- # PR is to print the files nicely. Use pr -n if available, or else just pr
- # I use a private utility called 'prt'
- PR=pr
-
- # NROFF is for nroffing. we use the System V nroff.
- NROFF=/usr/5bin/nroff
-
- # MANSEC is where to put the manual pages. Use 'l' for local, otherwise '1'.
- MANSEC=l
-
- # DESTBIN is where se and scriptse will go
- DESTBIN= /usr/local/bin
-
- # OWNER and GROUP are the owner and group respectively
- OWNER= root
- GROUP= sys
-
- # INSTALL is the program to do the installation, use cp for real work
- INSTALL= cp
-
- # CHOWN changes the owner.
- CHOWN= /etc/chown
-
- # CHGRP changes the group.
- CHGRP= chgrp
-
- # CHMOD will change permissions.
- CHMOD= chmod
-
- ########
- # other things to change:
- #
- # on non-BSD systems, change the 'lpr' below to 'lp'
- ########
-
- # Begin list of dependencies
-
- all: se scriptse se.1
- @echo all done
-
- se: $(OBJS) $(LIBRARIES)
- if grep DBSD flags > /dev/null || grep US5R2 flags > /dev/null; \
- then echo -ltermlib > libs; \
- else echo -lcurses > libs ; \
- fi
- -if [ -f /lib/shlib.ifile ] ; \
- then ld /lib/crt0s.o /lib/shlib.ifile $(OBJS) $(LIBRARIES) -o $@ ; \
- else $(CC) $(LDFLAGS) $(OBJS) $(LIBRARIES) `cat libs` -o $@ ; \
- fi
- rm libs
-
- $(OBJS): $(HEADERS) flags
-
- flags: where
- ./where > flags
-
- libchangetty/libchangetty.a: libchangetty/changetty.c
- cd libchangetty; make
-
- pat/libpat.a: pat/pat.c
- cd pat; make
-
- scriptse: scriptse.c
- $(CC) -O scriptse.c -o scriptse
-
- se.1: se.m4 flags
- (./m4munge $(CFLAGS) ; cat se.m4) | m4 | sed '/^$$/d' > se.1
-
- install: all $(MANS)
- $(INSTALL) se $(DESTBIN)
- $(CHOWN) $(OWNER) $(DESTBIN)/se
- $(CHGRP) $(GROUP) $(DESTBIN)/se
- $(CHMOD) 711 $(DESTBIN)/se
- $(INSTALL) scriptse $(DESTBIN)
- $(CHOWN) $(OWNER) $(DESTBIN)/scriptse
- $(CHGRP) $(GROUP) $(DESTBIN)/scriptse
- $(CHMOD) 711 $(DESTBIN)/scriptse
- $(INSTALL) se.1 /usr/man/man$(MANSEC)/se.$(MANSEC)
- $(CHOWN) $(OWNER) /usr/man/man$(MANSEC)/se.$(MANSEC)
- $(CHGRP) $(GROUP) /usr/man/man$(MANSEC)/se.$(MANSEC)
- $(CHMOD) 644 /usr/man/man$(MANSEC)/se.$(MANSEC)
- $(INSTALL) scriptse.1 /usr/man/man$(MANSEC)/scriptse.$(MANSEC)
- $(CHOWN) $(OWNER) /usr/man/man$(MANSEC)/scriptse.$(MANSEC)
- $(CHGRP) $(GROUP) /usr/man/man$(MANSEC)/scriptse.$(MANSEC)
- $(CHMOD) 644 /usr/man/man$(MANSEC)/scriptse.$(MANSEC)
- cd se_h; make install
-
- print:
- $(PR) $(HEADERS) $(SRCS) $(DOCS) $(MANS) | lpr
-
- printman: $(MANS)
- $(NROFF) -man $(MANS) | col | lpr
-
- print2: $(HEADERS) $(SRCS) $(DOCS) $(MANS)
- $(PR) $? | lpr
-
- printall: printman print
- cd pat; make print
- cd libchangetty; make print
- cd se_h; make print
-
- clean:
- rm -f *.o print2
- cd pat; make clean
- cd libchangetty; make clean
-
- clobber: clean
- rm -f se scriptse flags se.1
- cd pat; make clobber
- cd libchangetty; make clobber
- cd se_h; make clobber
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'misc.c'" '(3315 characters)'
- if test -f 'misc.c'
- then
- echo shar: will not over-write existing file "'misc.c'"
- else
- cat << \SHAR_EOF > 'misc.c'
- #ifndef lint
- static char RCSid[] = "$Header: misc.c,v 1.1 86/05/06 13:37:51 osadr Exp $";
- #endif
-
- /*
- * $Log: misc.c,v $
- * Revision 1.1 86/05/06 13:37:51 osadr
- * Initial revision
- *
- *
- */
-
- /*
- ** misc.c
- **
- ** lots of miscellanious routines for the screen editor.
- */
-
- #include "se.h"
- #include "extern.h"
-
- /* cprow --- copy from one row to another for append */
-
- cprow (from, to)
- register int from, to;
- {
- register int col;
-
- for (col = 0; col < Ncols; col++)
- load (Screen_image[from][col], to, col);
- }
-
- /* index --- return position of character in string */
-
- int index (str, c)
- register char str[], c;
- {
- register int i;
-
- for (i = 0; str[i] != EOS; i++)
- if (str[i] == c)
- return (i);
- return (-1);
- }
-
- /* strbsr --- binary search stab for an entry equal to str */
-
- int strbsr (stab, tsize, esize, str)
- char *stab, str[];
- int tsize, esize;
- {
- /* stab should have been declared like this:
-
- static struct {
- char *s;
- ...
- } stab[] = {
- "string1", ...
- "string2", ...
- ... ...
- };
-
- The call to strbsr should look like this:
-
- i = strbsr (stab, sizeof (stab), sizeof (stab[0]), str);
- */
-
- register int i, j, k, x;
- int strcmp ();
-
- i = 0;
- j = tsize / esize - 1;
- do {
- k = (i + j) / 2;
- if ((x = strcmp (str, *(char **)(stab + esize * k))) < 0)
- j = k - 1; /* GREATER */
- else if (x == 0)
- return (k); /* EQUAL */
- else
- i = k + 1; /* LESS */
- } while (i <= j);
-
- return (EOF);
- }
-
- /* strmap --- map a string to upper/lower case */
-
- int strmap (str, ul)
- register char str[];
- int ul;
- {
- register int i;
-
- if (isupper (ul))
- for (i = 0; str[i] != '0'; i++)
- str[i] = islower (str[i]) ? toupper (str[i]) : str[i];
- else
- for (i = 0; str[i] == EOS; i++)
- str[i] = isupper (str[i]) ? tolower (str[i]) : str[i];
- return (i);
- }
-
-
- /* xindex --- invert condition returned by index */
-
- int xindex (array, c, allbut, lastto)
- char array[], c;
- int allbut, lastto;
- {
- int index ();
-
- if (c == EOS)
- return (-1);
- if (allbut == NO)
- return (index (array, c));
- if (index (array, c) > -1)
- return (-1);
- return (lastto + 1);
- }
-
-
- /* ctoi --- convert decimal string to a single precision integer */
-
- int ctoi (str, i)
- register char str[];
- register int *i;
- {
- register int ret;
-
- SKIPBL (str, *i);
- for (ret = 0; isdigit (str[*i]); (*i)++)
- ret = ret * 10 + (str[*i] - '0');
- return (ret);
- }
-
-
- /* move_ --- move l bytes from here to there */
-
- move_ (here, there, l)
- register char *here, *there;
- register int l;
- {
- while (l--)
- *there++ = *here++;
- }
-
-
- /* twrite --- stuff characters into the terminal output buffer */
-
- twrite (fd, buf, len)
- register int fd, len;
- register char *buf;
- {
-
- if ((Tobp - Tobuf) + 1 + len > MAXTOBUF)
- tflush ();
-
- if (fd != 1 || len > MAXTOBUF)
- {
- write (fd, buf, len);
- return;
- }
-
- while (len--)
- *++Tobp = *buf++;
- }
-
-
- /* tflush --- clear out the terminal output buffer */
-
- tflush ()
- {
- write (1, Tobuf, (int)(Tobp - Tobuf + 1));
- Tobp = Tobuf - 1;
- }
-
-
-
- /* basename -- return last portion of a pathname */
-
- char *basename (str)
- register char *str;
- {
- register char *cp;
- #ifdef USG
- #define rindex strrchr
- #endif
- char *rindex ();
-
- if ((cp = rindex(str, '/')) == NULL)
- return (str); /* no '/' found, return whole name */
- else
- return (++cp); /* skip over slash to name after it */
- }
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-